package com.getpebble.android.framework.protocol.inbound;

import com.getpebble.android.bluetooth.protocol.ProtocolMessage;
import com.getpebble.android.framework.protocol.EndpointId;
import com.getpebble.android.framework.util.ByteUtils;
import com.google.common.primitives.UnsignedInteger;
import java.nio.ByteBuffer;

public class PblInboundCoreDumpMessage extends PblInboundMessage {
    private UnsignedInteger mByteOffset;
    private CoreDumpError mError;
    private ByteBuffer mImageData;
    private UnsignedInteger mNumBytes;
    private CoreDumpResponse mResponse;
    private byte mTransactionId;

    public enum CoreDumpError {
        NO_ERROR((byte) 0),
        MALFORMED_REQUEST((byte) 1),
        ALREADY_IN_PROGRESS((byte) 2),
        IMAGE_DOES_NOT_EXIST((byte) 3),
        IMAGE_CORRUPT((byte) 4);
        
        private byte mCode;

        private CoreDumpError(byte code) {
            this.mCode = code;
        }

        public byte getCode() {
            return this.mCode;
        }

        public static CoreDumpError fromCode(byte code) {
            for (CoreDumpError error : values()) {
                if (error.getCode() == code) {
                    return error;
                }
            }
            return null;
        }
    }

    public enum CoreDumpResponse {
        IMAGE_INFO((byte) 1),
        IMAGE_DATA((byte) 2);
        
        private byte mCode;

        private CoreDumpResponse(byte code) {
            this.mCode = code;
        }

        public byte getCode() {
            return this.mCode;
        }

        public static CoreDumpResponse fromCode(byte code) {
            for (CoreDumpResponse response : values()) {
                if (response.getCode() == code) {
                    return response;
                }
            }
            return null;
        }
    }

    public PblInboundCoreDumpMessage(ProtocolMessage message) {
        super(message);
        ByteBuffer buffer = message.getDataBuffer();
        this.mResponse = CoreDumpResponse.fromCode(buffer.get());
        this.mTransactionId = buffer.get();
        if (this.mResponse.equals(CoreDumpResponse.IMAGE_INFO)) {
            this.mError = CoreDumpError.fromCode(buffer.get());
            this.mNumBytes = ByteUtils.getUint32FromBuffer(buffer);
        } else if (this.mResponse.equals(CoreDumpResponse.IMAGE_DATA)) {
            this.mByteOffset = ByteUtils.getUint32FromBuffer(buffer);
            this.mImageData = ByteBuffer.allocate(buffer.remaining());
            this.mImageData.put(buffer);
            this.mImageData.position(0);
        }
    }

    public CoreDumpResponse getResponse() {
        return this.mResponse;
    }

    public byte getTransactionId() {
        return this.mTransactionId;
    }

    public CoreDumpError getError() {
        return this.mError;
    }

    public UnsignedInteger getNumBytes() {
        return this.mNumBytes;
    }

    public UnsignedInteger getByteOffset() {
        return this.mByteOffset;
    }

    public ByteBuffer getImageData() {
        return this.mImageData;
    }

    EndpointId getId() {
        return EndpointId.CORE_DUMP;
    }

    protected int getMinSize() {
        return 7;
    }
}
